/**
* Linkenstein  - Google Chrome extension for advanced hyperlink copying.
* Copyright (C) 2013  Mykola Bespaliuk
*/
/*global chrome, analytics */
var linkenstein = linkenstein || {};
/**
 * Id of html element that will be used for copying
 */
linkenstein.clipboardHolderId = '';
/**
 * Storage for main application data
 */
linkenstein.dataHolder = {
    title: null,
    url: null,
    keyCode: null,
    innerTitle: ''
};
/**
 * Gets the keyCode and innerText of the clicked link
 * @param tab
 */
linkenstein.getClickDetails = function( info, tab, callback ) {
    //noinspection JSUnresolvedVariable, JSUnresolvedFunction
    chrome.tabs.sendMessage( tab.id, { request: "getTargetInnerText" }, function( response ) {
        linkenstein.dataHolder.innerTitle   = response.innerText;
        //noinspection JSUnresolvedVariable, JSUnresolvedFunction
        chrome.tabs.sendMessage( tab.id, { request: "getKeyCode" }, function( response ) {
            linkenstein.dataHolder.keyCode = response.keyCode;
            callback( info, tab );
        } );
    });

};
/**
 * Entry point
 * @param info Information about context of the clicked element
 * @param tab Information about tab where menu was clicked
 */
linkenstein.initiate = function ( info, tab ) {

    linkenstein.dataHolder.url = linkenstein.dataHolder.title = linkenstein.dataHolder.keyCode = null;
    linkenstein.dataHolder.innerTitle = '';

    analytics.trackMenuClick();

    linkenstein.getClickDetails( info, tab, linkenstein.getUrl );
};

/**
 * Getting url of clicked link, or of the current tab or frame if
 * something else was clicked.
 * @param info Information about context of the clicked element
 * @param tab Information about tab where menu was clicked
 */
linkenstein.getUrl = function ( info, tab ) {

    if ( info.menuItemId === "frame_menu" ) {
	linkenstein.dataHolder.url   = info.frameUrl;
	analytics.trackLinkType( analytics.links.frameUrl );
    } else if ( typeof info.linkUrl !== "undefined" ) {
        //noinspection JSUnresolvedVariable
        linkenstein.dataHolder.url   = info.linkUrl;
        analytics.trackLinkType( analytics.links.inPage );
    } else {
        linkenstein.dataHolder.url   = tab.url;
        linkenstein.dataHolder.title = tab.title;
        analytics.trackLinkType( analytics.links.page )
    }

    if( linkenstein.dataHolder.url == null ) {
        return false;
    } else {
        linkenstein.processUrl( linkenstein.dataHolder.url );
    }
};
/**
 * Logic of the application options
 * @param url
 */
linkenstein.processUrl = function( url ) {
    var optionMapping   = linkenstein.optionMapping.option_use_short_url,
        triggerMapping  = linkenstein.optionMapping.option_short_url_trigger,
        selectedOption  = localStorage['option_use_short_url'],
        selectedTrigger = localStorage['option_short_url_trigger'];

    if( linkenstein.dataHolder.keyCode == triggerMapping[selectedTrigger] ) {
        analytics.trackHotKeyUse( selectedTrigger );
        switch( selectedOption ) {
            case( optionMapping.use_goo_gl.name ):
                optionMapping.use_goo_gl.callback( url );
                analytics.trackServiceUsed( analytics.services.use_goo_gl );
                break;
            case( optionMapping.use_tiny_url.name ):
                optionMapping.use_tiny_url.callback( url );
                analytics.trackServiceUsed( analytics.services.use_tiny_url );
                break;
            default:
                optionMapping.keep_long_url.callback( url );
        }
    } else {
        analytics.trackServiceUsed( analytics.services.keep_long_url );
        optionMapping.keep_long_url.callback( url );
    }

};

/**
 * Set current url to short version and get page title by original url
 * @param shortUrl String
 */
linkenstein.processShortUrl = function ( shortUrl ) {
    var oldUrl = linkenstein.dataHolder.url;
    if( shortUrl.length != 0 ) {
        linkenstein.dataHolder.url =  shortUrl;
    }
    linkenstein.getPageTitle( oldUrl );
};

/**
 * Get short version of url using Google URL shortener API
 * @param url String
 */
linkenstein.useGooGl = function ( url ) {
    urlshortener.insert( url, linkenstein.processShortUrl );
};

/**
 * Get short version of url using TinyURL site
 * @param url
 */
linkenstein.useTinyUrl = function( url ) {
    tinyurl.callback = linkenstein.processShortUrl;
    tinyurl.makeTiny( url );
};

/**
 * Getting page title by url
 * If we already have a title ( assuming the current tab title ) - proceed
 * If we have a link name longer that 10 character - proceed with it
 * Else try to follow the page and get it's title
 * @param url
 */
linkenstein.getPageTitle = function ( url ) {

    if( linkenstein.dataHolder.title != null ) {
        linkenstein.processResult( linkenstein.copyToClipboard );
        return true;
    } else if( linkenstein.dataHolder.innerTitle != null && linkenstein.dataHolder.innerTitle.length > 10 ) {
        linkenstein.dataHolder.title = linkenstein.dataHolder.innerTitle;
        linkenstein.processResult( linkenstein.copyToClipboard );
    } else {
        request.get( { url: url, async: true }, linkenstein.matchTitle );
    }
};

/**
 * Get page title from the given page source
 * @param pageCode
 */
linkenstein.matchTitle = function( pageCode ) {

    var titlePattern = /<title>([^<]*?)<\/title>/i,
    title = pageCode.match( titlePattern );

    if( title !== null ) {
        linkenstein.dataHolder.title = title[1];
    } else {
        linkenstein.dataHolder.title = linkenstein.dataHolder.innerTitle || '';
    }

    linkenstein.processResult( linkenstein.copyToClipboard );
};

/**
 * Clean up  title and concatenate it with the url of the link
 * @param callback
 */
linkenstein.processResult = function ( callback ) {

    var result = removeExtraneousSpaces( htmlEntitiesDecode(
            removeLineBreaks(
                    trim( linkenstein.dataHolder.title )
            )
    ) ) + "\n" + linkenstein.dataHolder.url;

    callback( result );

};

/**
 * Puts the given value into clipboard
 * @param value
 */
linkenstein.copyToClipboard = function ( value ) {

    var clipboardHolder;
    clipboardHolder                 = document.getElementById( linkenstein.clipboardHolderId );
    clipboardHolder.style.display   = "block";
    clipboardHolder.value           = value;
    clipboardHolder.select();
    document.execCommand("Copy");
    clipboardHolder.style.display   = "none";

};

/**
 * Mapping of application's options that might be present in localStorage
 */
linkenstein.optionMapping = {
    option_use_short_url: {
        keep_long_url: { name: "keep_long_url", callback: linkenstein.getPageTitle },
        use_goo_gl: { name: "use_goo_gl", callback: linkenstein.useGooGl },
        use_tiny_url: { name: "use_tiny_url", callback: linkenstein.useTinyUrl }
    },
    option_short_url_trigger: {
        "Shift": 16,
        "Ctrl": 17
    }
};
